package com.example.forum.services.impl;

import com.example.forum.common.AppResult;
import com.example.forum.common.ResultCode;
import com.example.forum.dao.UserMapper;
import com.example.forum.exception.ApplicationException;
import com.example.forum.model.User;
import com.example.forum.services.IUserService;
import com.example.forum.utils.FileUtil;
import com.example.forum.utils.MD5Util;
import com.example.forum.utils.StringUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.io.IOException;
import java.util.Date;

/**
 * Created with IntelliJ IDEA.
 * Description: 用户服务层实现类
 * User: DELL
 * Date: 2023-09-16
 * Time: 23:17
 */
@Slf4j
@Service
public class UserServiceImpl implements IUserService {

    @Resource
    private UserMapper userMapper;

    @Override
    public void createNormalUser(User user) {
        // 1.非空校验
        if (user == null || StringUtil.isEmpty(user.getUsername())
                || StringUtil.isEmpty(user.getNickname())
                || StringUtil.isEmpty(user.getPassword())
                || StringUtil.isEmpty(user.getSalt())) {
            // 打印日志
            log.warn(ResultCode.FAILED_PARAMS_VALIDATE.toString());
            // 抛出异常
            throw new ApplicationException(AppResult.fail(ResultCode.FAILED_PARAMS_VALIDATE));
        }
        // 2.按用户名查询用户信息
        User exitUser = userMapper.selectByUsername(user.getUsername());
        if (exitUser != null) {
            // 打印日志
            log.warn(ResultCode.FAILED_USER_EXISTS.toString());
            // 抛出异常
            throw new ApplicationException(AppResult.fail(ResultCode.FAILED_USER_EXISTS));
        }
        // 3.新增用户
        // 3.1 设置默认值
        user.setGender((byte) 2);
        user.setArticleCount(0);
        user.setIsAdmin((byte) 0);
        user.setState((byte) 0);
        user.setDeleteState((byte) 0);
        // 3.2 设置时间
        Date date = new Date();
        user.setCreateTime(date);
        user.setUpdateTime(date);
        // 3.3 写入数据库
        int row = userMapper.insertSelective(user);
        if (row != 1) {
            // 打印日志
            log.error(ResultCode.FAILED_CREATE.toString() + ". username = " + user.getUsername() + ".");
            // 抛出异常
            throw new ApplicationException(AppResult.fail(ResultCode.FAILED_CREATE));
        }
        // 打印日志
        log.info("新增用户成功. username = " + user.getUsername() + ".");
    }

    @Override
    public User selectByUsername(String username) {
        // 非空检验
        if (StringUtil.isEmpty(username)) {
            // 打印日志
            log.warn(ResultCode.FAILED_PARAMS_VALIDATE.toString());
            // 抛出异常
            throw new ApplicationException(AppResult.fail(ResultCode.FAILED_PARAMS_VALIDATE));
        }
        return userMapper.selectByUsername(username);
    }

    @Override
    public User login(String username, String password) {
        // 1.非空校验
        if (StringUtil.isEmpty(username) || StringUtil.isEmpty(password)) {
            // 打印日志
            log.warn(ResultCode.FAILED_PARAMS_VALIDATE.toString());
            // 抛出异常
            throw new ApplicationException(AppResult.fail(ResultCode.FAILED_LOGIN));
        }
        // 2.按用户名查询用户信息
        User user = userMapper.selectByUsername(username);
        // 3.对查询到的用户信息进行检验
        if (user == null) {
            // 打印日志
            log.warn(ResultCode.FAILED_USER_NOT_EXISTS.toString() + ". username = " + username + ".");
            // 抛出异常
            throw new ApplicationException(AppResult.fail(ResultCode.FAILED_LOGIN));
        }
        // 4.验证密码是否正确
        String salt = user.getSalt();
        String ciphertext = MD5Util.md5(password, salt);
        if (!ciphertext.equals(user.getPassword())) {
            // 打印日志
            log.warn("密码错误: username = " + username + "; password = " + password + ".");
            // 抛出异常
            throw new ApplicationException(AppResult.fail(ResultCode.FAILED_LOGIN));
        }
        // 5.返回结果
        // 打印日志
        log.info("用户登录成功: username = " + username + ".");
        return user;
    }

    @Override
    public User selectById(Long id) {
        // 1.非空校验
        if (id == null || id < 0) {
            // 打印日志
            log.warn(ResultCode.FAILED_PARAMS_VALIDATE.toString());
            // 抛出异常
            throw new ApplicationException(AppResult.fail(ResultCode.FAILED_PARAMS_VALIDATE));
        }
        // 2.调用 dao 查询数据库并返回对象
        return userMapper.selectByPrimaryKey(id);
    }

    @Override
    public void addOneArticleCountById(Long id) {
        // 参数校验
        if (id == null || id <= 0) {
            // 打印日志
            log.warn(ResultCode.FAILED_PARAMS_VALIDATE.toString());
            // 抛出异常
            throw new ApplicationException(AppResult.fail(ResultCode.FAILED_PARAMS_VALIDATE));
        }
        // 查询对应的板块
        User user = userMapper.selectByPrimaryKey(id);
        if (user == null) {
            // 打印日志
            log.warn(ResultCode.FAILED_USER_ARTICLE_COUNT.toString() + ",user id = " + id);
            // 抛出异常
            throw new ApplicationException(AppResult.fail(ResultCode.FAILED_USER_ARTICLE_COUNT));
        }
        // 更新数据库
        User updateUser = new User();
        updateUser.setId(id);
        updateUser.setArticleCount(user.getArticleCount() + 1);
        int row = userMapper.updateByPrimaryKeySelective(updateUser);
        if (row != 1) {
            // 打印日志
            log.warn(ResultCode.FAILED_USER_ARTICLE_COUNT.toString() + ",受影响的行数不为 1");
            // 抛出异常
            throw new ApplicationException(AppResult.fail(ResultCode.FAILED_USER_ARTICLE_COUNT));
        }
    }

    @Override
    public void delOneArticleCountById(Long id) {
        // 参数校验
        if (id == null || id <= 0) {
            // 打印日志
            log.warn(ResultCode.FAILED_PARAMS_VALIDATE.toString());
            // 抛出异常
            throw new ApplicationException(AppResult.fail(ResultCode.FAILED_PARAMS_VALIDATE));
        }
        int row = userMapper.delOneArticleCountById(id);
        if (row != 1) {
            // 打印日志
            log.warn(ResultCode.FAILED_USER_ARTICLE_COUNT.toString());
            // 抛出异常
            throw new ApplicationException(AppResult.fail(ResultCode.FAILED_USER_ARTICLE_COUNT));
        }
    }

    @Override
    public void update(User user) {
        // 参数校验
        if (user == null || user.getId() == null || user.getId() <= 0) {
            // 打印日志
            log.warn(ResultCode.FAILED_PARAMS_VALIDATE.toString());
            // 抛出异常
            throw new ApplicationException(AppResult.fail(ResultCode.FAILED_PARAMS_VALIDATE));
        }
        // 当要修改用户名时,检验用户名是否唯一
        if (user.getUsername() != null) {
            User selectUser = userMapper.selectByUsername(user.getUsername());
            if (selectUser != null && selectUser.getDeleteState() == 0) {
                // 打印日志
                log.warn(ResultCode.FAILED_USERNAME_EXISTS.toString());
                // 抛出异常
                throw new ApplicationException(AppResult.fail(ResultCode.FAILED_USERNAME_EXISTS));
            }
        }
        // 调用 dao,更新
        int row = userMapper.updateByPrimaryKeySelective(user);
        if (row != 1) {
            // 打印日志
            log.warn("更新用户信息异常," + user);
            // 抛出异常
            throw new ApplicationException(AppResult.fail(ResultCode.ERROR_SERVICES));
        }
    }

    @Override
    public String uploadAvatar(Long id, MultipartFile file) {
        // 非空校验
        if (id == null || id <= 0 || file == null || file.isEmpty()) {
            // 打印日志
            log.warn(ResultCode.FAILED_PARAMS_VALIDATE.toString());
            // 抛出异常
            throw new ApplicationException(AppResult.fail(ResultCode.FAILED_PARAMS_VALIDATE));
        }
        // 保存头像
        String filePath = null;
        try {
            filePath = FileUtil.saveFile(file);
        } catch (IOException e) {
            throw new ApplicationException("Failed to save file", e);
        }
        // 生成更新对象
        User updateUser = new User();
        updateUser.setId(id);
        updateUser.setAvatarUrl(filePath);
        // 调用 dao 层,更新数据库
        int row = userMapper.updateByPrimaryKeySelective(updateUser);
        if (row != 1) {
            // 打印日志
            log.warn("更新用户信息异常," + updateUser);
            // 抛出异常
            throw new ApplicationException(AppResult.fail(ResultCode.ERROR_SERVICES));
        }
        // 返回数据
        return filePath;
    }
}
